#ifndef DECODER_H
#define DECODER_H
#include "ffinc.h"
#include "PacketQueue.h"
#include <functional>
#include <thread>
#include <memory>
using namespace std;
/**
 * @brief 自定义解码器封装
 */
class Decoder
{
public:
    Decoder();
    ~Decoder();

public:
    /**
     * @brief 初始化解码器
     * @param avctx: 解码器上下文
     * @param queue: 对应的包队列
     * @param cond: read_thread配合的信号量
     * @return 0成功，其他失败
     */
    int init(AVCodecContext *avctx, shared_ptr<PacketQueue> queue, SDL_cond *cond);
    /**
     * @brief 关闭解码器
     */
    void destroy();
    /**
     * @brief 讲AVPacket解码为AVFrame
     * @param frame: 解码后的帧
     * @return 1 获取到帧，0 读完了 -1 请求退出
     */
    int decoder_decode_frame(AVFrame *frame);

public:
    AVPacket *pkt;
    shared_ptr<PacketQueue> queue;	// 数据包队列
    AVCodecContext *avctx;			// 解码器上下文
    uint32_t pkt_serial;			// 包序列
    int finished;					// =0, 解码器处于工作状态；=非0，解码器处于空闲状态
    int packet_pending;				// =0，解码器处于异常状态，需要考虑重置解码器；=1，解码器处于正常状态
    SDL_cond *empty_queue_cond;		// 检查到packet队列空时发送 signal缓存read_thread读取数据
    int64_t start_pts;				// 初始化时是stream的start time
    AVRational start_pts_tb;		// 初始化时是stream的time
    int64_t next_pts;				// 记录最近一次解码后的frame的pts，当解出来的部分帧没有有效的pts时则使⽤next_pts进⾏推算
    AVRational next_pts_tb;			// next_pts的单位
};
#endif // DECODER_H
